#include<iostream>
#include<unistd.h>
#include<string>
#include<string.h>
#include<vector>
#include<functional>
#include <sys/types.h>
#include <sys/wait.h>

// int main()
// {
//     int fds[2]={0};
//     int n = pipe(fds);
//     if(n != 0)
//     {
//         perror("pipe");
//         return -1;
//     }

//     std::cout << "内核" << std::endl;
//     std::cout << "内核" << std::endl;
//     std::cout << "内核" << std::endl;
//     std::cout << "内核" << std::endl;


//     std::cerr << "收到华工科技发的" << std::endl;
//     std::cerr << "收到华工科技发的" << std::endl;
//     std::cerr << "收到华工科技发的" << std::endl;
//     std::cerr << "收到华工科技发的" << std::endl;

//     return 0;
// }

// int main()
// {
//     int fds[2];
//     int n = pipe(fds);
//     if(n < 0)
//     {
//         perror("pipe");
//         exit(1);
//     }
//     int id = fork();
//     if(id  < 0)
//     {
//         perror("fork");
//         exit(2);
//     }
//     else if(id == 0)
//     {
//         //子进程
//         ::close(fds[0]);
//         int cun = 0;
//         while(true)
//         {
//             std::string name = "数据，";
//             name += std::to_string(getpid());
//             name += ",";
//             name += std::to_string(cun);
//             ::write(fds[1],name.c_str(),name.size());
//             sleep(1);
//             cun++;
//         }
//         exit(0);
//     }
//     else
//     {
//         //父进程
//         ::close(fds[1]);
//         char buff[1024];
//         while(true)
//         {
//             int n = ::read(fds[0],buff,sizeof(buff));
//             if(n > 0)
//             {
//                 std::cout << "子进程发送的数据："<< buff << std::endl;
//             }
//         }
//         int rid = ::waitpid(id,nullptr,0);
//         if(rid > 0)
//         {
//             std::cout << "等待子进程成功" << std::endl;
//         }
//     }
//     return 0;
// }

using wk_t = std::function<void()>;

enum
{
    ok = 0,
    sagerr,
    pipeerr,
    foekerr
};

void arge(std::string argv)
{
    std::cout << "这样用:" << argv << "程序名字-数字:创建子进程个数" << std::endl;
}

class pipe_test
{
public:
    pipe_test(int wfd,int who):_wfd(wfd),_who(who)
    {
        _name = "管道-描述符" + std::to_string(_wfd) + "管道pid："+ std::to_string(_who);
    }

    std::string Name()
    {
        return _name;
    }

    ~pipe_test()
    {

    }
private:
    int _wfd;//标识
    std::string _name;//管道名字
    pid_t _who;       //给管道一个pid_t表示是给那个子进程的
};
//创建管道，进程池
//work_t work是回调，C++11讲过,让子进程执行不同任务
void proce(int& num,std::vector<pipe_test>& ps,wk_t wotk)
{
    for(int i = 0;i<num ;i++)
    {
        //创建管道
        int fds[2];
        int n = pipe(fds);
        if(n < 0) exit(1);

        pid_t id = fork();
        //3.建立通信信道
        if(id == 0)
        {
            ::close(fds[1]);
            //我想让子进程都从标准输入读未来的命令
            //pipefd管道让读端，从标准输入里读
            dup2(fds[0],0);
            wotk();//执行任务

            ::exit(1);
        }
        //父进程执行
        ::close(fds[0]);

        ps.emplace_back(fds[1],id);

    }
}

void test()
{
    std::cout << "测试中" << std::endl;
}

void wk_printf(std::vector<pipe_test>& ps)
{
    for(auto& i: ps)
    {
        std::cout << i.Name() << std::endl;
    }
}

int main(int argc,char* argv[])
{
    if(argc != 2)
    {
        //告诉用户怎么用
        arge(argv[1]);
        exit(0);
    }
    //将用户输入的字符串转换成整形
    int num = std::stoi(argv[1]);

    //vector管道每一个管道类
    std::vector<pipe_test> pipe_d;

    proce(num,pipe_d,test);

    wk_printf(pipe_d);

    return 0;
}